vimfandomcom-20200223-history
Use grep to get a clickable list of function names
The following function will make a :cwindow window with a line per function in the current C source file. NOTE: It writes the file as a side effect. Invoke with ':call ShowFunc()' You may want to do :nmap :call ShowFunc() function! ShowFunc() let gf_s = &grepformat let gp_s = &grepprg let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m' let &grepprg = 'ctags -x --c-types=f --sort=no -o -' write silent! grep % cwindow let &grepformat = gf_s let &grepprg = gp_s endfunc Comments Some enhancements courtesy of Bill McCarthy: > let &grepprg = 'ctags -x --c-types=f --sort=no -o -' or just: let &grepprg = 'ctags -x --c-types=f --sort=no' since the '-o -' is redundant with '-x'. > write or better yet: update which will not change the filedate on a file that hasn't changed. ---- I'd suggest that the call to write or update (as noted in the note above) be changed to: if (&readonly 0) | update | endif so that you don't get an error message when attempting this on a read only file. ---- For some reason this fails in vim6.0au under unix with file names longer than about 14 characters. however, if you change let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m' to let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %m' then it works fine regardless of file name length. running on a terminal, if there are a lot of functions in a file then the screen tends to get messed up, which can be fixed by insering a call to redraw after the cwindow call, so you get: silent! grep % cwindow redraw let &grepformat = gf_s Ok, couple of small bugs and mistakes fixed. Try this version: function! ShowFunc(sort) let gf_s = &grepformat let gp_s = &grepprg if ( &filetype "c" || &filetype "php" || &filetype "python" || \ &filetype "sh" ) let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --'.&filetype.'-types=f --sort='.a:sort elseif ( &filetype "perl" ) let &grepformat='%*\k%*\ssubroutine%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --perl-types=s --sort='.a:sort elseif ( &filetype "vim" ) let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --vim-types=f --language-force=vim --sort='.a:sort endif if (&readonly 0) | update | endif silent! grep % cwindow 10 redraw let &grepformat = gf_s let &grepprg = gp_s endfunc I map this function to F3 to produce a list in the order the functions appear in the file or Shift-F3 to list them in alphabetical order. noremap :call ShowFunc("no") noremap :call ShowFunc("yes") And last be sure you have Exuberant CTags installed or it won't work. ---- Try this for Java: elseif ( &filetype "java" ) let &grepformat='%*\k%*\sclass%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --java-types=c --sort='.a:sort If this produces blank results, then you can try changing the last line to: let &grepprg = 'ctags -x --java-types=c --language-force=java --sort='.a:sort I increased the number of file types supported to 19. You can now search for 1. Classes - Java 2. Functions - Awk, C, C++, Fortran, Lisp, Pascal, PHP, Python, Ruby, Shell Scripts, Scheme, Slang, and Vim 3. Macros - Makefiles 4. Procedures - Expect, and Tcl 5. Subroutines - Perl and Rexx C, Shell Scripts, Vim, Expect, Tcl and Perl are well tested. The rest work on the few tests that I have given them. Let me know of any bugs and I'll work them out. Additionally, I changed it so that it opens a dynamically sized cwindow based on the height of the window it was called from and/or the number of links in the results. An empty search returns a cwindow a single line tall. Last, I packaged this function as to make it easier to install, and to get it out of my vimrc file. ----